About HTML Tidy

Introduction to TIDY

When editing HTML it's easy to make mistakes. Wouldn't it be nice if there was a simple way to fix these mistakes automatically and tidy up sloppy editing into nicely layed out markup? Well now there is! Dave Raggett's HTML TIDY is a free utility for doing just that. It also works great on the atrociously hard to read markup generated by specialized HTML editors and conversion tools, and can help you identify where you need to pay further attention on making your pages more accessible to people with disabilities.

Tidy is able to fix up a wide range of problems and to bring to your attention things that you need to work on yourself. Each item found is listed with the line number and column so that you can see where the problem lies in your markup. Tidy won't generate a cleaned up version when there are problems that it can't be sure of how to handle. These are logged as "errors" rather than "warnings".

Examples of TIDY at work

Tidy corrects the markup in a way that matches where possible the observed rendering in popular browsers from Netscape and Microsoft. Here are just a few examples of how TIDY perfects your HTML for you:

Layout style

You can choose which style you want Tidy to use when it generates the cleaned up markup: for instance whether you like elements to indent their contents or not. Several people have asked if Tidy could preserve the original layout. I am sorry to say that this would be very hard to support due to the way Tidy is implemented. Tidy starts by building a clean parse tree from the source file. The parse tree doesn't contain any information about the original layout. Tidy then pretty prints the parse tree using the current layout options. Trying to preserve the original layout would interact badly with the repair operations needed to build a clean parse tree and considerably complicate the code.

Some browsers can screw up the right alignment of text depending on how you layout headings. As an example, consider:

<h1 align="right">
  Heading
</h1>

<h1 align="right">Heading</h1>

Both of these should be rendered the same. Sadly a common browser bug fails to trim trailing whitespace and misaligns the first heading. HTML Tidy will protect you from this bug, except when you set the indent option to "yes".

Setting the indent option to yes can also cause problems with table layout for some browsers:

<td><img src="foo.gif"></td>
<td><img src="foo.gif"></td>

will look slightly different from:

<td>
  <img src="foo.gif">
</td>
<td>
  <img src="foo.gif">
</td>

You can avoid such quirks by using indent: no or indent: auto in the config file.

Internationalization issues

Tidy offers you a choice of character encodings: US ASCII, ISO Latin-1, UTF-8 and the ISO 2022 family of 7 bit encodings. The full set of HTML 4.0 entities are defined. Cleaned up output uses HTML entity names for characters when appropriate. Otherwise characters outside the normal range are output as numeric character entities. Tidy defaults to assuming you want the output to be in US ASCII. Tidy doesn't yet recognize the use of the HTML meta element for specifying the character encoding.

Accessibility

Tidy offers advice on accessibility problems for people using non-graphical browsers. The most common thing you will see is the suggestion you add a summary attribute to table elements. The idea is to provide a summary of the table's role and structure suitable for use with aural browsers.

Cleaning up presentational markup

Many tools generate HTML with an excess of FONT, NOBR and CENTER tags. Tidy's -clean option will replace them by style properties and rules using CSS. This makes the markup easier to read and maintain as well as reducing the file size! Tidy is expected to get smarter at this in the future.

Some pages rely on the presentation effects of isolated <p> or </p> tags.Tidy deletes empty paragraph and heading elements etc. The use of empty paragraph elements is not recommended for adding vertical whitespace. Instead use style sheets, or the <br> element. Tidy won't discard paragraphs only containing a nonbreaking space &nbsp;

Teaching Tidy about new tags!

You can teach Tidy about new tags by declaring them in the configuration file, the syntax is:

  new-inline-tags: tag1, tag2, tag3
  new-empty-tags: tag1, tag2, tag3
  new-blocklevel-tags: tag1, tag2, tag3
  new-pre-tags: tag1, tag2, tag3

The same tag can be defined as empty and as inline or as empty and as block.

These declarations can be combined to define an a new empty inline or empty block element, but you are not advised to declare tags as being both inline and block!

Note that the new tags can only appear where Tidy expects inline or block-level tags respectively. This means you can't (yet) place new tags within the document head or other contexts with restricted content models. So far the most popular use of this feature is to allow Tidy to be applied to Cold Fusion files.

I am working on ways to make it easy to customize the permitted document syntax using assertion grammars, and hope to apply this to a much smarter version of Tidy for release later this year or early next year.

Limited support for ASP, JSTE and PHP

Tidy is somewhat aware of the preprocessing language called ASP which uses a pseudo element syntax <% ... %> to include preprocessor directives. ASP is normally interpreted by the web server before delivery to the browser. JSTE shares the same syntax, but sometimes also uses <# ... #>. Tidy can also cope with another such language called PHP, which uses the syntax <?php ... ?>

Tidy will cope with ASP, JSTE and PHP pseudo elements within element content and as replacements for attributes, for example:

  <option <% if rsSchool.Fields("ID").Value
    = session("sessSchoolID")
    then Response.Write("selected") %>
    value='<%=rsSchool.Fields("ID").Value%>'>
    <%=rsSchool.Fields("Name").Value%>
    (<%=rsSchool.Fields("ID").Value%>)
  </option>

Note that Tidy doesn't understand the scripting language used within pseudo elements and attributes, and can easily get confused. Tidy may report missing attributes when these are hidden within preprocessor code. Tidy can also get things wrong if the code includes quote marks, e.g. if the example above is changed to:

    value="<%=rsSchool.Fields("ID").Value%>"

Tidy will now see the quote mark preceding ID as ending the attribute value, and proceed to complain about what follows. Note you can choose whether to allow line wrapping on spaces within pseudo elements or not using the wrap-asp option. If you used ASP, JSTE or PHP to create a start tag, but placed the end tag explicitly in the markup, Tidy won't be able to match them up, and will delete the end tag for you. So in this case you are advise to make the start tag explicit and to use ASP, JSTE or PHP for just the attributes, e.g.

   <a href="<%=random.site()%>">do you feel lucky?</a>

Tidy allows you to control whether line wrapping is enabled for ASP, JSTE and PHP instructions, see the wrap-asp, wrap-jste and wrap-php config options, respectively.

I regret that Tidy does not support Tango preprocessing instructions which look like:

<@if variable_1='a'>
    do something
<@else>
    do nothing
</@if>

<@include <@cgi><@appfilepath>includes/message.html>

Tidy supports another preprocessing syntax called "Tango", but only for attribute values. Adding support for pseudo elements written in Tango looks as if it would be quite tough, so I would like to gauge the level of interest before committing to this work.

Limited support for XML

XML processors compliant with W3C's XML 1.0 recommendation are very picky about which files they will accept. Tidy can help you to fix errors that cause your XML files to be rejected. Tidy doesn't yet recognize all XML features though, e.g. it doesn't understand CDATA sections or DTD subsets.